﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Skylabs.Net;

namespace Skylabs.Breeze
{
    public static class Server
    {
        public static TcpListener Listener { get; set; }
        public static List<Client> Clients { get; set; }
        public static List<FileReceiver> FileReceivers { get; set; }
        private static int curIndex = 0;
        public static void Start()
        {
            Program.ServerTrace.TraceInformation("Server Starting");
            Clients = new List<Client>();
            FileReceivers = new List<FileReceiver>();
            if(Listener == null)
                Listener = new TcpListener(IPAddress.Any, 7678);
            try
            {
                Listener.Start(1);
                AcceptClients();
            }
            catch (Exception e)
            {
                Program.ServerTrace.TraceEvent(TraceEventType.Error,0,e.Message);
            }
            
        }
        public static void TransferDone(FileReceiver fr)
        {
            Program.ServerTrace.TraceInformation("File '{0}' Transfered.{1}-{2}", fr.FileName, fr.TotalBytesReceived, fr.TotalSize);
            FileReceivers.Remove(fr);
        }
        public static void ClientHello(Client c, string filename)
        {
            var fr = FileReceivers.FirstOrDefault(t => t.FileName == filename);

            if (fr == null)
            {
                fr = new FileReceiver(filename);
                FileReceivers.Add(fr);
            }
            c.Parent = fr;
            fr.Clients.Add(c);

            Clients.Remove(c);
        }
        public static void Stop()
        {
            Program.ServerTrace.TraceInformation("Server Stopping");
            try
            {
                Listener.Stop();
            }
            catch (Exception e)
            {
                Program.ServerTrace.TraceEvent(TraceEventType.Error, 0, e.Message);
            }
        }
        private static void AcceptClients()
        {
            Listener.BeginAcceptTcpClient(OnClientConnect, null);
        }
        private static void OnClientConnect(IAsyncResult o)
        {
            try
            {
                TcpClient c = Listener.EndAcceptTcpClient(o);
                Clients.Add(new Client(c, curIndex));
                curIndex++;
                if (curIndex == int.MaxValue)
                    curIndex = 0;
                //Program.ServerTrace.TraceInformation("Client connected.");
                AcceptClients();
            }
            catch (ObjectDisposedException)
            {

            }
        }
    }
}
